package com.abou.mvc.controller;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import com.abou.constant.product.ECategory;
import com.abou.constant.product.EClotheType;
import com.abou.model.admin.Credentials;
import com.abou.mvc.editor.CommonsMultipartFileEditor;
import com.abou.utils.common.DateUtils;

/**
 * The class defining utility methods for controllers.
 */
public class ControllerUtils {
  
  /**
   * The logger
   */
  private static final Logger LOGGER = Logger.getLogger(ControllerUtils.class);
  
  /**
   * The name of the attribute used to override the selected main menu item name
   */
  public static final String OVERRIDE_MAIN_MENUITEM_NAME =
      "overrideMainMenuItemName";
  
  /**
   * The HTTP GET method name
   */
  public static final String HTTP_GET = "GET";
  
  /**
   * The HTTP POST method name
   */
  public static final String HTTP_POST = "POST";
  
  /**
   * The suffix for all the view names
   */
  public static final String VIEW_NAME_SUFFIX = ".do";
  
  /**
   * The name of the attribute used to store the link to the previous page
   */
  public static final String BACK_ATT = "back";
  
  /**
   * The param used to notify that an update was successful
   */
  public static final String UPDATE_SUCCESS_PARAM = "updated";
  
  /**
   * The param value used to notify that an update was successful
   */
  public static final String UPDATE_SUCCESS_VALUE = "1";
  
  /**
   * The path separator
   */
  public static final String PATH_SEP = ".";
  
  /**
   * The hours and minutes separator
   */
  public static final String HOURS_MINUTES_SEP = ":";
  
  /**
   * The printable strings separator
   */
  public static final String PRINTABLE_SEP = " ";
  
  /**
   * The redirect instruction
   */
  public static final String REDIRECT_INSTR = "redirect:/";
  
  /**
   * The path separator
   */
  public static final String VIEW_PATH_SEP = "/";
  
  /**
   * The URL parameters delimiter
   */
  public static final String PARAMS_DEL = "?";
  
  /**
   * The URL parameters separator
   */
  public static final String PARAMS_SEP = "&";
  
  /**
   * The separator between a URL parameter and its value
   */
  public static final String PARAMS_VAL_SEP = "=";
  
  /**
   * The name of the attribute used to modify the current theme
   */
  public static final String THEME_NAME_ATT = "themeName";
  
  /**
   * The name of the attribute used to identify a product
   */
  public static final String PRODUCT_ID_ATT = "productId";
  
  /**
   * The name of the attribute used to modify the current locale
   */
  public static final String LOCALE_ATT = "locale";
  
  /**
   * The resource folder
   */
  public static final String RES_FOLDER = "res";
  
  /**
   * The image folder
   */
  public static final String IMG_FOLDER = "img";
  
  /**
   * The constant defining the prefix for each enumeration constant label code
   */
  public static final String ENUM_LABEL_CODE_PREFIX = "";
  
  /**
   * The UTF-8 encoding
   */
  public static final String UTF8_ENCODING = "UTF-8";
  
  /**
   * The LATIN-1 encoding
   */
  public static final String LATIN1_ENCODING = "ISO-8859-1";
  
  /**
   * The empty values label code
   */
  public static final String EMPTY_VALUES_CODE = "value.empty";
  
  /**
   * The filename header attribute
   */
  public static final String FILE_NAME_HEADER_ATT = "Content-Disposition";
  
  /**
   * The filename header attribute value prefix
   */
  public static final String FILE_NAME_HEADER_ATT_VALUE_PREFIX =
      "inline; filename=";
  
  /**
   * The parameter value for the ascending sort order
   */
  public static final String SORT_ORDER_ASC = "2";
  
  /**
   * The parameter value for the descending sort order
   */
  public static final String SORT_ORDER_DESC = "1";
  
  /**
   * The logout view
   */
  public static final String LOGOUT_PATH = "j_spring_security_logout";
  
  /**
   * The constant defining the name of the communication types array
   */
  public static final String COM_TYPES_ATT = "comTypes";
  
  /**
   * The name of the param used to reset a form
   */
  public static final String RESET_PARAM = "reset";
  
  /**
   * The name of the attribute for the user time zone
   */
  public static final String TIME_ZONE_ATT = "timeZone";
  
  /**
   * The name of the attribute storing the request values for a search
   */
  public static final String SEARCH_REQUEST_ATT = "searchProductsRequest";
  
  /**
   * The name of the attribute storing the result of a search
   */
  public static final String SEARCH_RESULT_ATT = "searchProductsResult";
  
  /**
   * The name of the attribute storing the product
   */
  public static final String PRODUCT_ATT = "product";
  
  /**
   * The name of the attribute storing the last consulted products
   */
  public static final String LAST_PRODUCTS_ATT = "lastConsultedProducts";
  
  /**
   * The constant defining the name of the parameter containing the rows number
   * per page to use
   */
  public static final String ROWS_NB_PER_PAGE_PARAM = "rowsNbPerPage";
  
  /**
   * The name of the value for the search page result modifier.
   */
  public static final String SEARCH_PAGE_NAME_MODIFIER_VAL = "result";
  
  /**
   * The name of the attribute storing the date pattern.
   */
  public static final String DATE_PATTERN_ATT = "datePattern";
  
  /**
   * The name of the attribute storing the date picker pattern.
   */
  public static final String DATE_PICKER_PATTERN_ATT = "datePickerPattern";
  
  /**
   * The name of the attribute storing the time picker pattern.
   */
  public static final String TIME_PICKER_PATTERN_ATT = "timePickerPattern";
  
  /**
   * The attribute name used to specify if a confirmation message should be
   * displayed
   */
  public static final String CONFIRMATION_ATT = "confirmFor";
  
  /**
   * The parameter value used to confirm the creation of an element
   */
  public static final String CREATED_CONFIRMATION = "created";
  
  /**
   * The parameter value used to confirm the modification of an element
   */
  public static final String MODIFIED_CONFIRMATION = "modified";
  
  /**
   * The parameter value used to confirm the deletion of an element
   */
  public static final String DELETED_CONFIRMATION = "deleted";
  
  /**
   * The parameter name used to notifying that the rows nb per page has been
   * modified
   */
  public static final String ROWS_NB_PER_PAGE_MODIFIED_PARAM = "rowsNbModif";
  
  /**
   * The name of the param used to update a status
   */
  public static final String NEW_STATUS_PARAM = "newStatus";
  
  /**
   * The constant defining the name of the parameter used to notify that a form
   * submission is done by means of a GET HTTP request.
   */
  public static final String SUBMIT_PARAM = "submit";
  
  /**
   * The private constructor to prevent the class from being instantiated
   */
  private ControllerUtils() {

    super();
  }
  
  /**
   * @param cat
   * @return
   */
  public static List<EClotheType> getEClotheTypes(ECategory cat) {

    List<EClotheType> clotheTypes = new ArrayList<EClotheType>();
    
    for (EClotheType clotheType : EClotheType.values()) {
      
      if (clotheType.name().contains("_" + cat.name())) {
        
        clotheTypes.add(clotheType);
      }
    }
    
    return clotheTypes;
  }
  
  /**
   * @return The current user session credentials
   */
  public static Credentials getCreds() {

    Authentication auth =
        SecurityContextHolder.getContext().getAuthentication();
    Credentials creds =
        new Credentials(auth.getName(), (String) auth.getCredentials());
    
    return creds;
  }
  
  /**
   * Converts the passed constant name into a message key.
   * 
   * @param constantName An enumeration constant name
   * @return The corresponding message key
   */
  public static String getMsgKey(String constantName) {

    String retValue = "";
    
    if (constantName != null) {
      
      retValue = constantName.toLowerCase().replace('_', '.');
    }
    
    return retValue;
  }
  
  /**
   * Returns the main menu item index for the page denoted by the passed page.
   * 
   * @param pagePath A page path
   * @return A main menu item index
   */
  public static String getMainMenuItemIndex(String pagePath) {

    String indexStr = "";
    
    if (!StringUtils.isBlank(pagePath)) {
      
      int index = -1;
      
      if (pagePath.contains("/fleet/")) {
        
        index = 0;
        
      } else if (pagePath.contains("/network/")) {
        
        index = 1;
      }
      
      if (index >= 0) {
        
        indexStr = String.valueOf(index);
      }
    }
    
    return indexStr;
  }
  
  /**
   * Creates a date formatter for the passed locale
   * 
   * @param locale A locale
   * @param request The current request
   * @return A date formatter
   */
  public static DateFormat getDateFormatter(HttpServletRequest request,
      Locale locale) {

    DateFormat dateFormatter =
        DateFormat.getDateInstance(SimpleDateFormat.SHORT, locale);
    dateFormatter.setLenient(false);
    DateUtils.setTimeZone(request, dateFormatter);
    
    return dateFormatter;
  }
  
  /**
   * Inits a the binder for a controller.
   * 
   * @param registry The property editors registry
   * @param request The current request
   * @param locale The current locale
   */
  public static void initBinder(PropertyEditorRegistry registry,
      HttpServletRequest request, Locale locale) {

    // creating the date editor
    DateFormat dateFormat = ControllerUtils.getDateFormatter(request, locale);
    
    // registering the date editor
    registry.registerCustomEditor(Date.class, new CustomDateEditor(
        dateFormat, true));
    
    // registering the date editor
    registry.registerCustomEditor(CommonsMultipartFile.class,
        new CommonsMultipartFileEditor());
  }
}
